package com.abigdreamer.im.server.module.msgProcess;

import java.util.List;

import org.apache.mina.core.session.IoSession;

import com.abigdreamer.im.message.BaseMessage;
import com.abigdreamer.im.message.FriendGroupMessage;
import com.abigdreamer.im.message.LoginMessage;
import com.abigdreamer.im.message.LoginResponseMessage;
import com.abigdreamer.im.message.MessageType;
import com.abigdreamer.im.message.RepeatLoginMessage;
import com.abigdreamer.im.server.log.EIMLogger;
import com.abigdreamer.im.server.module.ServerCache;
import com.abigdreamer.im.server.module.UserConnect;
import com.abigdreamer.im.server.module.vo.MsgFriendGroup;
import com.abigdreamer.im.server.module.vo.MsgFriendGroupList;
import com.abigdreamer.im.server.module.vo.MsgTeam;
import com.abigdreamer.im.server.module.vo.MsgTeamList;
import com.abigdreamer.im.server.module.vo.MsgUser;
import com.thoughtworks.xstream.XStream;

/**
 * 服务器登陆消息(LoginMessage)处理器
 */
public class LoginMessageProcess implements IMessageProcess {

	public void processMessage(BaseMessage message) {
		LoginMessage loginMessage = (LoginMessage) message;
		String owerQQ = loginMessage.getOwerQQ();
		EIMLogger.INFO("服务器正在处理登陆消息!!!!");
		// 获取服务器缓存
		ServerCache cache = ServerCache.getInstance();
		// 从服务器缓存中根据登陆消息的唯一的LoginID获取用户连接对象
		UserConnect userConnect = cache.getUserConnectMap().get(loginMessage.getLoginID());
		LoginResponseMessage loginResponse = getLoginResponse(loginMessage);
		userConnect.sendTextTempMessage(loginResponse);
		if (loginResponse.getLoginResponse() == MessageType.LoginResponse_Faile) {
			EIMLogger.INFO("某用户" + loginMessage.getOwerQQ() + " 登入失败！~");
		} else {
			UserConnect onlieConnect = processOnlieUserConnect(userConnect.getTextTempSession(), owerQQ);
			processLoginSucess(onlieConnect);
		}
		cache.getUserConnectMap().remove(loginMessage.getLoginID());
		EIMLogger.INFO("在线人数:" + cache.getUserConnectMap().size());

	}

	/**
	 * 登陆验证
	 * 
	 * @param loginMessage
	 * @return 根据loginMessage来获得LoginResponseMessage 验证此次登陆的合法性
	 */
	private LoginResponseMessage getLoginResponse(LoginMessage loginMessage) {
		String owerQQ = loginMessage.getOwerQQ();
		String pwd = loginMessage.getPwd();
		// 获取服务器缓存
		ServerCache cache = ServerCache.getInstance();
		// 从服务器缓存中根据owerQQ得到MsgUser对象
		MsgUser user = cache.getAllUserMap().get(owerQQ);
		// 创建登陆消息相应包
		LoginResponseMessage loginResponseMessage = new LoginResponseMessage();
		loginResponseMessage.setMsgType(MessageType.LoginResponseMessage_Type);
		loginResponseMessage.setDestQQ(owerQQ);
		loginResponseMessage.setSrcQQ(MessageType.sysQQ);
		if (null == user) {// 如果得到的MsgUser对象为空说明ID用问题
			loginResponseMessage.setLoginResponse(MessageType.LoginResponse_Faile);
			loginResponseMessage.setErrorReason(MessageType.LoginResponse_Faile_QQReason);
		} else if (!user.getPassWord().equals(pwd)) {// 如果得到的MsgUser对象密码不对则说明pwd用问题
			loginResponseMessage.setLoginResponse(MessageType.LoginResponse_Faile);
			loginResponseMessage.setErrorReason(MessageType.LoginResponse_Faile_PwdReason);
		} else {// 如果两项都对则说明此用户是合格的
			loginResponseMessage.setLoginResponse(MessageType.LoginResponse_Succee);
		}
		return loginResponseMessage;
	}

	/**
	 * 确保单点登陆
	 * 
	 * @param textTempSession
	 * @param owerQQ
	 * @return
	 * 
	 *         根据owerQQ和零时textTempSession去在服务器中保存连接 2种情况：
	 *         1:此号已经登陆了，则把原有的连接断去，从连接列表删除 2:还没登陆，则建立创建一个新的UserConnect保存连接列表中
	 * 
	 */
	private UserConnect processOnlieUserConnect(IoSession textTempSession, String owerQQ) {
		ServerCache cache = ServerCache.getInstance();
		UserConnect onlieUserConnect = cache.getUserConnectMap().get(owerQQ);
		if (null != onlieUserConnect) {
			RepeatLoginMessage repeatLoginMessage = new RepeatLoginMessage(owerQQ);
			// 获取再次登陆的IP
			String repeatLoginIP = textTempSession.getLocalAddress().toString();
			repeatLoginMessage.setRepeatLoginIP(repeatLoginIP);
			onlieUserConnect.getTextSession().write(repeatLoginMessage);
			EIMLogger.Error("此QQ已经登录了");
			try {
				Thread.sleep(1 * 1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			onlieUserConnect.getTextSession().closeOnFlush();
			cache.getUserConnectMap().remove(owerQQ);
		} else {
			onlieUserConnect = new UserConnect();
		}
		onlieUserConnect.setOwerQQ(owerQQ);
		onlieUserConnect.setTextSession(textTempSession);
		onlieUserConnect.getTextSession().setAttribute("owerQQ", owerQQ);
		cache.getUserConnectMap().put(owerQQ, onlieUserConnect);
		EIMLogger.INFO("某用户" + owerQQ + " 登入成功！~");
		return onlieUserConnect;
	}

	/**
	 * 
	 * @param onlieConnect
	 * 
	 *            登陆成功后做的处理 1:自己的基本信息 2:好友列表信息 3:群列表信息
	 */
	private void processLoginSucess(UserConnect onlieConnect) {

		String owerQQ = onlieConnect.getOwerQQ();
		ServerCache cache = ServerCache.getInstance();

		MsgUser user = cache.getAllUserMap().get(owerQQ);
		user.setOnline(true);
		cache.addUserToOnLineList(owerQQ, user);

		MsgUser ower = cache.getAllUserMap().get(owerQQ);
		List<MsgFriendGroup> friendGroups = cache.getAllFriendGroupList();// 好友列表信息
		List<MsgTeam> teams = cache.getAllTeamList();// 群列表信息

		FriendGroupMessage groupMessage = new FriendGroupMessage(owerQQ);
		groupMessage.setFriendGroupXML(getFriendGroupXML(friendGroups));
		groupMessage.setTeamXML(getTeamXML(teams));
		onlieConnect.sendTextMessage(groupMessage);
		EIMLogger.INFO("服务器给 某用户" + owerQQ + " 发送个好友列表信息！~");
	}

	public String getFriendGroupXML(List<MsgFriendGroup> friendGroups) {
		XStream xstream = new XStream();
		xstream.alias("FriendGrous", MsgFriendGroupList.class);
		xstream.alias("friendGroup", MsgFriendGroup.class);
		xstream.alias("user", MsgUser.class);
		xstream.addImplicitCollection(MsgFriendGroupList.class, "FriendGroups");
		xstream.addImplicitCollection(MsgFriendGroup.class, "userList");
		MsgFriendGroupList friendGroupList = new MsgFriendGroupList();
		friendGroupList.setFriendGroups(friendGroups);
		return xstream.toXML(friendGroupList);
	}

	public String getTeamXML(List<MsgTeam> teams) {
		XStream xstream = new XStream();
		xstream.alias("Teams", MsgTeamList.class);
		xstream.alias("team", MsgTeam.class);
		xstream.alias("user", MsgUser.class);
		xstream.addImplicitCollection(MsgTeamList.class, "teams");
		xstream.addImplicitCollection(MsgTeam.class, "userList");
		MsgTeamList teamList = new MsgTeamList();
		teamList.setTeams(teams);
		return xstream.toXML(teamList);

	}
}
